// ==UserScript==
// @name         pmc 批处理插件
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  try to take over the world!
// @author       awei
// @noframes     false                   // 允许注入到iframe/子窗口
// @match        https://www.cpmcpimc.com:9036/*
// @require      https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js
// @grant        none

// ==/UserScript==


(function() {
    'use strict';
    load();
    // Your code here...
})();




async function load(){
    // 载入公共api库
    let url = window.location.href;
    if(url.indexOf("business-process-use-tab")>=0){
        business_process_fun();
    }

}

function business_process_fun(){
    //批处理时载入的方法
    console.log("载入批处理方法");
    addXMLRequestCallback( function( xhr ) {
        // 调用劫持函数，填入一个function的回调函数
        // 回调函数监听了对xhr调用了监听load状态，并且在触发的时候再次调用一个function，进行一些数据的劫持以及修改
        xhr.addEventListener("load", function(){
            if ( xhr.readyState == 4 && xhr.status == 200 ) {
                let url = xhr.responseURL;
                if (url.indexOf("openFormList")>=0){
                    console.log("已拦截报表信息数据");
                    //console.log(xhr);
                    // 将 responseText 转为 JSON
                    const jsonData = JSON.parse(xhr.responseText);
                    // 打印 JSON 数据
                    console.log('JSON 数据:', jsonData);
                    const mainData = jsonData["data"]["mainDataList"];
                    window.location.mainData = mainData;
                    setTimeout(() => {
                        console.log("1 秒后执行！");
                        // 防抖后的回调（0.5秒内最多触发一次）
                        const debouncedCallback = debounce(() => {
                            // 选择 #pane-first 下所有 tr，排除第一个
                            $("#pane-first tr").not(":first").each(function() {
                                this.style.setProperty('height', '300px', 'important');
                            });
                            const processedRows = new Set();
                            mainData.forEach((value) => {
                                const main_id = value["bp_main_id"];
                                const task_id = value["task_id@@dms"];
                                // 添加错误处理，当NCR_IMG或id不存在时返回空字符串
                                const img_src = value["NCR_IMG"] && value["NCR_IMG"]["id"]
                                ? "/api/dms-security-server/pimepc/file/" + value["NCR_IMG"]["id"]
                                : "";

                                if (!processedRows.has(main_id)) {
                                    modifySpecificTd(main_id, "col_57", img_src);
                                    //modifySpecificTd(main_id, "col_32", "");
                                    set_value(main_id, "col_63", "新疆油建");
                                    set_value(main_id, "col_66", value["Job_Loc"]);
                                    set_value(main_id, "col_67", "已整改");
                                    add_jump_button(main_id, "col_31", value);
                                    processedRows.add(main_id);
                                }
                            });
                        }, 500);
                        // 添加一个动态监视器， 在vue的表格重新渲染时， 再次修改表格的格式
                        // 目标表格的容器（例如通过 ID 或 class 选择）
                        const tableContainer = document.getElementById('pane-first');

                        // 创建观察器，监听子元素（tr/td）的变化
                        const observer = new MutationObserver((mutations) => {
                            mutations.forEach((mutation) => {
                                // 当表格内容变化时，执行你的逻辑
                                if (mutation.type === 'childList') {
                                    //console.log("表格发生变化");
                                    debouncedCallback();
                                }
                            });
                        });

                        // 开始观察
                        observer.observe(tableContainer, {
                            childList: true,  // 监听子节点变化
                            subtree: true     // 递归监听所有后代节点
                        });



                    }, 1000); // 3000 毫秒 = 3 秒

                }

            }
        });

    });



}


function addXMLRequestCallback(callback){
    // 是一个劫持的函数
    var oldSend, i;
    if( XMLHttpRequest.callbacks ) {
        //   判断XMLHttpRequest对象下是否存在回调列表，存在就push一个回调的函数
        // we've already overridden send() so just add the callback
        XMLHttpRequest.callbacks.push( callback );
    } else {
        // create a callback queue
        XMLHttpRequest.callbacks = [callback];
        // 如果不存在则在xmlhttprequest函数下创建一个回调列表
        // store the native send()
        oldSend = XMLHttpRequest.prototype.send;
        // 获取旧xml的send函数，并对其进行劫持
        // override the native send()
        XMLHttpRequest.prototype.send = function(){
            // process the callback queue
            // the xhr instance is passed into each callback but seems pretty useless
            // you can't tell what its destination is or call abort() without an error
            // so only really good for logging that a request has happened
            // I could be wrong, I hope so...
            // EDIT: I suppose you could override the onreadystatechange handler though
            for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
                XMLHttpRequest.callbacks[i]( this );
            }
            // 循环回调xml内的回调函数
            // call the native send()
            oldSend.apply(this, arguments);
            //    由于我们获取了send函数的引用，并且复写了send函数，这样我们在调用原send的函数的时候，需要对其传入引用，而arguments是传入的参数
        }
    }
}


function getTableRowByIndex(divId, index) {
    // 1. 获取 div 元素
    const div = document.getElementById(divId);
    if (!div) {
        //console.error(`未找到 ID 为 "${divId}" 的 div`);
        return null;
    }

    // 2. 获取 div 下的第一个 table
    const table = div.querySelector('table');
    if (!table) {
        //console.error(`未找到 div 下的 table`);
        return null;
    }

    // 3. 获取 table 的所有 tr
    const rows = table.querySelectorAll('tr');
    if (index < 0 || index >= rows.length) {
        //console.error(`索引 ${index} 超出范围（有效范围：0 ~ ${rows.length - 1}）`);
        return null;
    }

    // 4. 返回指定索引的 tr
    return rows[index];
}


function modifySpecificTd(rowid, colid, imgUrl) {
    // 1. 查找目标 tr（带 rowid 属性）
    const $targetTr = $(`tr[rowid="${rowid}"]`);

    // 2. 如果找不到 tr，直接返回
    if (!$targetTr.length) {
        //console.log(`未找到 rowid="${rowid}" 的 tr`);
        return;
    }

    const col = $(`col[name="${colid}"]`);
    col.css({
        width: '300px',

    });

    // 3. 在目标 tr 中查找带指定 colid 的 td
    const $targetTd = $targetTr.find(`td[colid="${colid}"]`);

    // 4. 如果找不到 td，直接返回
    if (!$targetTd.length) {
        //console.log(`在 rowid="${rowid}" 的行中未找到 colid="${colid}" 的 td`);
        return;
    }

    // 5. 修改 td 样式（不破坏 Vue 响应式）
    $targetTd.css({
        width: '300px',
        border: '2px solid blue' // 可选：调试用边框
    });
    $targetTd[0].style.setProperty('height', '300px', 'important');
    // 6. 清空 td 并插入图片
    if(imgUrl != ""){
        // 创建图片元素
        const $img = $('<img>', {
            src: imgUrl,
            alt: '动态插入的图片',
            style: 'width: 100%; height: 100%; object-fit: cover'
        });

        // 绑定双击事件
        $img.dblclick(function() {
            // 创建模态框
            const $modal = $(`
            <div style="
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                display: flex;
                justify-content: center;
                align-items: center;
                z-index: 9999;
            ">
                <img src="${imgUrl}" style="max-width: 90%; max-height: 90%;">
                <div style="
                    position: absolute;
                    top: 20px;
                    right: 20px;
                    color: white;
                    font-size: 30px;
                    cursor: pointer;
                ">×</div>
            </div>
        `);

            // 点击关闭
            $modal.find('div').click(function() {
                $modal.remove();
            });

            // 添加到body
            $('body').append($modal);
        });

        $targetTd.empty().append($img);
    }


    //console.log(`成功修改 rowid="${rowid}" 中 colid="${colid}" 的 td`, $targetTd[0]);
}

function set_value(rowid, colid, value){
    // 1. 查找目标 tr（带 rowid 属性）
    const $targetTr = $(`tr[rowid="${rowid}"]`);

    // 2. 如果找不到 tr，直接返回
    if (!$targetTr.length) {
        //console.log(`未找到 rowid="${rowid}" 的 tr`);
        return;
    }
    // 3. 在目标 tr 中查找带指定 colid 的 td
    const $targetTd = $targetTr.find(`td[colid="${colid}"]`);
    // 4. 如果找不到 td，直接返回
    if (!$targetTd.length) {
        //console.log(`在 rowid="${rowid}" 的行中未找到 colid="${colid}" 的 td`);
        return;
    }

    // 同时查找 input 或 textarea
    const inputElement = $targetTd.find('input, textarea')[0];

    if (!inputElement) {
        //console.log(`在 rowid="${rowid}" 的行中未找到 input 或 textarea`);
        return;
    }

    // 创建合适的事件类型（input适用于两者）
    const eventType = inputElement.tagName.toLowerCase() === 'textarea' ? 'input' : 'input';
    const ev = new Event(eventType, { bubbles: true });

    setTimeout(() => {
        if (inputElement) {
            inputElement.value = value;
            inputElement.dispatchEvent(ev);

            // 对于某些框架可能需要额外触发change事件
            inputElement.dispatchEvent(new Event('change', { bubbles: true }));
        }
    }, 100);
}

/**
 * 在指定列添加跳转按钮（仿照你的set_value风格）
 * @param {string} rowid - 行ID
 * @param {string} colid - 要插入按钮的列ID
 * @param {string} taskId - 用于生成URL2的taskId（从当前行获取）
 */
function add_jump_button(rowid, colid, rowData) {
    // 1. 查找目标 tr（保持与你代码一致的查找逻辑）
    const $targetTr = $(`tr[rowid="${rowid}"]`);
    if (!$targetTr.length) {
        console.log(`未找到 rowid="${rowid}" 的 tr`);
        return;
    }

    // 2. 查找目标列
    const $targetTd = $targetTr.find(`td[colid="${colid}"]`);
    if (!$targetTd.length) {
        console.log(`在 rowid="${rowid}" 的行中未找到 colid="${colid}" 的 td`);
        return;
    }

    // 3. 创建按钮元素（使用你的代码风格的事件触发方式）
    const button = document.createElement('button');
    button.className = 'btn-jump-url2';
    button.textContent = '处理任务';
    //button.dataset.taskId = taskId; // 存储taskId用于后续跳转

    // 4. 清空列内容并添加按钮
    $targetTd.empty().append(button);

    // 5. 绑定点击事件（模仿你的set_value事件触发逻辑）
    button.addEventListener('click', function() {
        let url = generate_url2_directly(rowData);
        window.open(url);
    });
}



/**
 * 从当前行JSON数据生成URL2（无需API调用）
 * @param {Object} rowData - 当前行的完整JSON数据
 * @returns {string} 可直接跳转的URL2
 */
function generate_url2_directly(rowData) {
    // 必选参数（全部能从JSON中获取）
    const params = new URLSearchParams({
        shellId: rowData.fk_shell_inst_id,          // 1095781528308285440
        pathId: 'bpbpssncr',                       // 与URL1保持一致
        isTab: '1',
        bpId: '4021',                              // 与URL1保持一致
        bpCode: 'bpbpssncr',
        policyId: rowData.fk_workflow_policy_id,   // 292995
        bpInsId: rowData.id,                       // 1110684728328978432
        type: 'edit',
        taskId: rowData['task_id@@dms'],           // 533322
        from: '1',
        sourcePathId: 'personalPendingTask',
        taskPageType: '/pending-task'
    });

    return `https://www.cpmcpimc.com:9036/#/business-process-use-tab1?${params.toString()}`;
}

function debounce(func, delay) {
    let timer = null;
    return function(...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(this, args);
            timer = null;
        }, delay);
    };
}

